From: Jonas Ã…dahl Date: Fri, 5 Sep 2025 13:53:52 +0000 (+0200) Subject: popupMenu: Queue relayout on popup menu parent when opening X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~88^2~9^2^2~6 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=1db4429d1b9e215c51df04ebd2bc5ebf36d45139;p=gnome-shell.git popupMenu: Queue relayout on popup menu parent when opening The position of the menu depends on the position of the "source actor", but the source actor is not a parent of the menu, but typically a sibling. Since we depend on the source actor position for placing the popup menu, it's important that the source actor gets allocated before we allocate. Currently the only way to ensure that the source actor is allocated before the popup menu is by handling the layout via the parent actor, as the order of the allocations done when queuing shallow relayouts is currently undefined. As of d94638acae ("clutter/actor: Make child position changes a noop when possible") in mutter, Clutter.Actor.set_child_above_sibling() has a fast path when the position doesn't change, which means the parent was did not get its relayout queued. This caused the popup menu to end up being allocated before the source actor, thus using an out of date source actor allocation to base its position calculation on. To fix this, queue a relayout on the parent actor unconditionally, after inserting it into the parent actor, to let us be able to rely on the source actor having been allocated before the popup menu itself getting allocated. Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/4253 Part-of: (cherry picked from commit ca198804598daf595d56600b76b0a0fd088252ee) --- diff --git a/js/ui/popupMenu.js b/js/ui/popupMenu.js index a068ced5e..76df95dae 100644 --- a/js/ui/popupMenu.js +++ b/js/ui/popupMenu.js @@ -1119,6 +1119,13 @@ export class PopupMenu extends PopupMenuBase { this.actor.get_parent().set_child_above_sibling(this.actor, null); + /* The position calculation expects the source actor allocation to be + * up to date, so queue relayout on parent to ensure it gets allocated + * first. + */ + if (!this.sourceActor?.has_allocation()) + this.sourceActor?.get_parent().queue_relayout(); + this.emit('open-state-changed', true); }